package edu.task.snake.controller;

import edu.task.snake.model.Cell;
import edu.task.snake.model.Frog;
import edu.task.snake.model.Snake;

import java.util.ArrayList;
import java.util.List;


public class SnakeController extends Thread implements Runnable {
    private Snake model;
    private GameEngine gameEngine;

    private boolean leftDirection;
    private boolean rightDirection;
    private boolean upDirection;
    private boolean downDirection;

    public SnakeController(Snake model, GameEngine gameEngine) {
        rightDirection = true;
        this.model = model;
        this.gameEngine = gameEngine;
    }

    public Snake getModel() {
        return model;
    }

    public void setModel(Snake model) {
        this.model = model;
    }

    public void move() {
        ArrayList<Cell> cells = model.getArrayList();
        Cell headCell = cells.get(cells.size() - 1);
        int size = cells.size() - 1;
        if (leftDirection) {
            cells.add(new Cell(headCell.getX() - 1, headCell.getY()));
            cells.remove(0);
        }

        if (rightDirection) {
            cells.add(new Cell(headCell.getX() + 1, headCell.getY()));
            cells.remove(0);
        }

        if (upDirection) {
            cells.add(new Cell(headCell.getX(), headCell.getY() - 1));
            cells.remove(0);
        }

        if (downDirection) {
            cells.add(new Cell(headCell.getX(), headCell.getY() + 1));
            cells.remove(0);
        }
        model.action();//todo
    }


    public void changeDirection(String move) {
        if (move.equals("left")) {
            if (leftDirection) {
                allDirectionReset();
                downDirection = true;
                return;
            }

            if (rightDirection) {
                allDirectionReset();
                upDirection = true;
                return;
            }
            if (upDirection) {
                allDirectionReset();
                leftDirection = true;
                return;
            }
            if (downDirection) {
                allDirectionReset();
                rightDirection = true;
                return;
            }
        } else if (move.equals("right")) {
            if (leftDirection) {
                allDirectionReset();
                upDirection = true;
                return;
            }

            if (rightDirection) {
                allDirectionReset();
                downDirection = true;
                return;
            }
            if (upDirection) {
                allDirectionReset();
                rightDirection = true;
                return;
            }
            if (downDirection) {
                allDirectionReset();
                leftDirection = true;
                return;
            }
        }
    }


    private void allDirectionReset() {
        leftDirection = false;
        rightDirection = false;
        upDirection = false;
        downDirection = false;
    }

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (gameEngine.isInGame()) {

                checkFrog();
                checkCollisionSnake();
                move();
            }
//            gameEngine.doDrawing(); ToDo add Listener to snake model
        }

    }

    private void checkFrog() {
        Cell head = model.getArrayList().get(model.getArrayList().size() - 1);
        Frog removeFrog = null;
        List<Frog> frogList = gameEngine.getFrogList();
        for (Frog frog : frogList) {
            if ((head.getX() == frog.getX()) && (head.getY() == frog.getY())) {

                //ToDo grows snake
                Cell last = model.getArrayList().get(0);
                Cell prelast = model.getArrayList().get(1);
                int newCellCoordinateX = last.getX() + (last.getX() - prelast.getX());
                int newCellCoordinateY = last.getY() + (last.getY() - prelast.getY());


                model.getArrayList().add(0, new Cell(newCellCoordinateX, newCellCoordinateY));

                removeFrog = frog;
                break;
            }
        }
        if (removeFrog != null) {
            frogList.remove(removeFrog);
            gameEngine.checkFreeSpace();
            gameEngine.killFrogProcess();//Todo kill frog process and create new if needed
//            frogList.add(gameEngine.initFrog());
        }
    }

    private void checkCollisionSnake() {
        int size = model.getArrayList().size() - 1;
        Cell head = model.getArrayList().get(size);
        for (int i = 0; i <= size - 1; i++) {
            Cell cell = model.getArrayList().get(i);

            if ((i > 4) && (head.getX() == cell.getX()) && (head.getY() == cell.getY())) {
                gameEngine.setInGame(false);
            }
        }

        if (head.getY() >= gameEngine.getCellHeight()) {
            gameEngine.setInGame(false);
        }

        if (head.getY() < 0) {
            gameEngine.setInGame(false);
        }

        if (head.getX() >= gameEngine.getCellWidth()) {
            gameEngine.setInGame(false);
        }

        if (head.getX() < 0) {
            gameEngine.setInGame(false);
        }

        if (!gameEngine.isInGame()) {
            gameEngine.stopGame();
        }
    }
}
